/*
The surface-physics project: http://code.google.com/p/surface-physics/
Adds real world physics based on the Bullet physics engine, to bases in the Orbiter space
flight simulation software.

Written by Abhijit Nandy
License : Apache License 2.0

Bump_BulletBase.h
BulletBase management directly from within Bump. Objects of this class are created
in the Bump module and uses a BulletBase VESSEL as a proxy for inserting meshes and attaching
objects. The BulletBase has no other role other than key forwarding (as of now) which is
difficult to do from a module. This class merges Orbiter and Bullet functionality towards
achieving the above outlined purpose.

This is possible due to the extensive public API of VESSEL & its derived classes.

This file declares the interface for the Bump_BulletBase class. Its role:
1. Creates the BulletBase proxy VESSEL at the location of the passed base
2. Reads the base specific physics file and staggers creation of objects in update()
   which is called at every sim step.
3. Reads command from a BulletBase public member and passes it on to components/attachments or
	processes them itself as reqd.
4. Scans the sky for nearby objects and attaches/detaches them as needed(does not scan in every step)


Do not store any global positions, or any positions, always get them again when needed(they all change)
OBJHANDLEs can be stored like handle to base or reference body. These wont change.


*/


#pragma once

#include "process.h"


#include "barrier.h"




class Bump_ThreadTargetInterface
{

public:
	Bump_ThreadTargetInterface(){}
	~Bump_ThreadTargetInterface(){}

	virtual int run() = 0;

};



class Bump_Thread
{

	//thread specific stuff;
	HANDLE hThread;
	unsigned threadID;
	bool keepRunningThread;
	bool threadRunning;
	char toutput[100];

	CRITICAL_SECTION critsec;

	Bump_ThreadBarrier *threadBarrier;
	Bump_ThreadTargetInterface *threadTarget;


public:



	Bump_Thread(Bump_ThreadTargetInterface *target, Bump_ThreadBarrier *barr)
	{
		threadTarget = target;
		threadBarrier = barr;
		keepRunningThread = true;
		hThread = (HANDLE)_beginthreadex(NULL , 0, &threadEntry, this, 0, &threadID);
	};

	~Bump_Thread()
	{
		CloseHandle(hThread);
	};

	static unsigned __stdcall threadEntry(void *param)
	{
		Bump_Thread *thrd = (Bump_Thread*)param;
		
		oapiWriteLog("thread created");

		thrd->threadRunning = true;

		while(thrd->keepRunningThread){
			thrd->threadTarget->run();
			thrd->threadBarrier->wait();
		}


		//sprintf_s(toutput, 1000, "%s%d", endgame, thrd->threadTarget->baseID);


		thrd->threadRunning = false;

		_endthreadex(0);
		return 0;



	}

	//Will be called from another thread.
	int stop()
	{
		keepRunningThread = false;
		return 0;
	}

	//Optional, iterations to wait before forcing the thread shut
	//Will be called from another thread.
	int join(long waitCount)
	{
		while(threadRunning)
			Sleep(100);			//to yield at regular intervals
		return 0;
	}

	void setBarrier(Bump_ThreadBarrier* barr){
		threadBarrier = barr;
	}

	Bump_ThreadBarrier* getBarrier(void){
		return threadBarrier;
	}

};


/**
 * The Bump_BulletBase to create and manage a BulletBase
 */
/*
class Base : public Bump_ThreadTargetInterface
{

	int baseID;

	volatile unsigned int count;

	char output[100];

public:

	Base(int id)
	{
		baseID = id;
		count = 0;

		//InitializeCriticalSection(&critsec);
	}

	virtual ~Base()
	{

		//DeleteCriticalSection(&critsec);

		sprintf(output, "Destroying Base:%d, count:%d", baseID, count);
		oapiWriteLog(output);
	};

	int run() // A member function
	{
		count++;
		sprintf(output, "Base:%d, count:%d", baseID, count);
		oapiWriteLog(output);

		return 0;
	}

};


*/
